﻿using System;
using System.Collections;
using UnityEngine;

namespace RootMotion.FinalIK
{
	// Token: 0x02000083 RID: 131
	public abstract class OffsetModifier : MonoBehaviour
	{
		// Token: 0x1700006F RID: 111
		// (get) Token: 0x060004EF RID: 1263 RVA: 0x000051CD File Offset: 0x000033CD
		public float deltaTime
		{
			get
			{
				return Time.time - this.lastTime;
			}
		}

		// Token: 0x060004F0 RID: 1264
		public abstract void OnModifyOffset();

		// Token: 0x060004F1 RID: 1265 RVA: 0x000051DB File Offset: 0x000033DB
		public virtual void Start()
		{
			base.StartCoroutine(this.Initiate());
		}

		// Token: 0x060004F2 RID: 1266 RVA: 0x00032184 File Offset: 0x00030384
		public IEnumerator Initiate()
		{
			while (this.ik == null)
			{
				yield return null;
			}
			IKSolverFullBodyBiped solver = this.ik.solver;
			solver.OnPreUpdate = (IKSolver.UpdateDelegate)Delegate.Combine(solver.OnPreUpdate, new IKSolver.UpdateDelegate(this.ModifyOffset));
			this.lastTime = Time.time;
			yield break;
		}

		// Token: 0x060004F3 RID: 1267 RVA: 0x000321A0 File Offset: 0x000303A0
		public void ModifyOffset()
		{
			if (!base.enabled)
			{
				return;
			}
			if (this.weight <= 0f)
			{
				return;
			}
			if (this.deltaTime <= 0f)
			{
				return;
			}
			if (this.ik == null)
			{
				return;
			}
			this.weight = Mathf.Clamp(this.weight, 0f, 1f);
			this.OnModifyOffset();
			this.lastTime = Time.time;
		}

		// Token: 0x060004F4 RID: 1268 RVA: 0x0003221C File Offset: 0x0003041C
		public void ApplyLimits(OffsetModifier.OffsetLimits[] limits)
		{
			foreach (OffsetModifier.OffsetLimits offsetLimits in limits)
			{
				offsetLimits.Apply(this.ik.solver.GetEffector(offsetLimits.effector), base.transform.rotation);
			}
		}

		// Token: 0x060004F5 RID: 1269 RVA: 0x000051EA File Offset: 0x000033EA
		public virtual void OnDestroy()
		{
			if (this.ik != null)
			{
				IKSolverFullBodyBiped solver = this.ik.solver;
				solver.OnPreUpdate = (IKSolver.UpdateDelegate)Delegate.Remove(solver.OnPreUpdate, new IKSolver.UpdateDelegate(this.ModifyOffset));
			}
		}

		// Token: 0x04000377 RID: 887
		[Tooltip("The master weight")]
		public float weight = 1f;

		// Token: 0x04000378 RID: 888
		[SerializeField]
		[Tooltip("Reference to the FBBIK component")]
		public FullBodyBipedIK ik;

		// Token: 0x04000379 RID: 889
		public float lastTime;

		// Token: 0x02000084 RID: 132
		[Serializable]
		public class OffsetLimits
		{
			// Token: 0x060004F7 RID: 1271 RVA: 0x0003226C File Offset: 0x0003046C
			public void Apply(IKEffector e, Quaternion rootRotation)
			{
				Vector3 point = Quaternion.Inverse(rootRotation) * e.positionOffset;
				if (this.spring <= 0f)
				{
					if (this.x)
					{
						point.x = Mathf.Clamp(point.x, this.minX, this.maxX);
					}
					if (this.y)
					{
						point.y = Mathf.Clamp(point.y, this.minY, this.maxY);
					}
					if (this.z)
					{
						point.z = Mathf.Clamp(point.z, this.minZ, this.maxZ);
					}
				}
				else
				{
					if (this.x)
					{
						point.x = this.SpringAxis(point.x, this.minX, this.maxX);
					}
					if (this.y)
					{
						point.y = this.SpringAxis(point.y, this.minY, this.maxY);
					}
					if (this.z)
					{
						point.z = this.SpringAxis(point.z, this.minZ, this.maxZ);
					}
				}
				e.positionOffset = rootRotation * point;
			}

			// Token: 0x060004F8 RID: 1272 RVA: 0x00005229 File Offset: 0x00003429
			public float SpringAxis(float value, float min, float max)
			{
				if (value > min && value < max)
				{
					return value;
				}
				if (value < min)
				{
					return this.Spring(value, min, true);
				}
				return this.Spring(value, max, false);
			}

			// Token: 0x060004F9 RID: 1273 RVA: 0x000323AC File Offset: 0x000305AC
			public float Spring(float value, float limit, bool negative)
			{
				float num = value - limit;
				float num2 = num * this.spring;
				if (negative)
				{
					return value + Mathf.Clamp(-num2, 0f, -num);
				}
				return value - Mathf.Clamp(num2, 0f, num);
			}

			// Token: 0x0400037A RID: 890
			[Tooltip("The effector type (this is just an enum)")]
			public FullBodyBipedEffector effector;

			// Token: 0x0400037B RID: 891
			[Tooltip("Spring force, if zero then this is a hard limit, if not, offset can exceed the limit.")]
			public float spring;

			// Token: 0x0400037C RID: 892
			[Tooltip("Which axes to limit the offset on?")]
			public bool x;

			// Token: 0x0400037D RID: 893
			[Tooltip("Which axes to limit the offset on?")]
			public bool y;

			// Token: 0x0400037E RID: 894
			[Tooltip("Which axes to limit the offset on?")]
			public bool z;

			// Token: 0x0400037F RID: 895
			[Tooltip("The limits")]
			public float minX;

			// Token: 0x04000380 RID: 896
			[Tooltip("The limits")]
			public float maxX;

			// Token: 0x04000381 RID: 897
			[Tooltip("The limits")]
			public float minY;

			// Token: 0x04000382 RID: 898
			[Tooltip("The limits")]
			public float maxY;

			// Token: 0x04000383 RID: 899
			[Tooltip("The limits")]
			public float minZ;

			// Token: 0x04000384 RID: 900
			[Tooltip("The limits")]
			public float maxZ;
		}
	}
}
